package cn.com.lyb.asyncTask.manage;


import cn.com.lyb.asyncTask.construnctor.AbstractAsyncTaskConstructor;
import cn.com.lyb.asyncTask.construnctor.AsyncTaskConstructor;
import cn.com.lyb.asyncTask.entity.TaskInfo;
import cn.com.lyb.asyncTask.entity.TaskStatusEnum;
import cn.com.lyb.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 异步任务管理器
 */
@Component
public class AsyncTaskManager {

    private Map<String, TaskInfo> taskContainer = new ConcurrentHashMap<>(16);

    @Autowired
    AsyncTaskExecutor asyncTaskExecutor;

    /**
     * 初始化任务
     *
     * @return taskInfo
     */
    private TaskInfo initTask() {
        TaskInfo taskInfo = new TaskInfo();
        taskInfo.setTaskUid(getTaskId());
        taskInfo.setStatus(TaskStatusEnum.STARTED);
        taskInfo.setStartTime(new Date());
        setTaskInfo(taskInfo);
        return taskInfo;
    }

    /**
     * 初始化任务
     * @param asyncTaskConstructor 异步任务构造器
     * @return taskInfo
     */
    public TaskInfo submit(AsyncTaskConstructor asyncTaskConstructor) {
        TaskInfo info = initTask();
        String taskUid = info.getTaskUid();
        if (asyncTaskConstructor instanceof AbstractAsyncTaskConstructor) {
            ((AbstractAsyncTaskConstructor) asyncTaskConstructor).setTaskUid(taskUid);
        }
        asyncTaskExecutor.executor(asyncTaskConstructor, taskUid);
        return info;
    }

    /**
     * 保存任务信息
     *
     * @param taskInfo 任务信息
     */
    public void setTaskInfo(TaskInfo taskInfo) {
        taskContainer.put(taskInfo.getTaskUid(), taskInfo);
    }

    /**
     * 获取任务信息
     *
     * @param taskUid 任务UID
     * @return
     */
    public TaskInfo getTaskInfo(String taskUid) {
        return taskContainer.get(taskUid);
    }

    /**
     * 获取任务状态
     *
     * @param taskId 任务ID
     * @return
     */
    public TaskStatusEnum getTaskStatus(String taskId) {
        return getTaskInfo(taskId).getStatus();
    }

    /**
     * 生成任务ID
     *
     * @return taskId
     */
    private String getTaskId() {
        return UUID.randomUUID().toString();
    }

    /**
     * 从缓存中移除相关任务信息
     * @param taskInfo
     */
    public void removeTaskInfo(TaskInfo taskInfo) {
        if (StringUtils.isNotEmpty(taskInfo.getTaskUid())) {
            removeTaskInfo(taskInfo.getTaskUid());
        }
    }

    /**
     * 从缓存中移除相关任务信息
     * @param taskUid
     */
    public void removeTaskInfo(String taskUid) {
        if (taskContainer.get(taskUid) != null) {
            taskContainer.remove(taskUid);
        }
    }

    /**
     * 暂停任务
     * @param taskUid
     */
    public void pauseTaskInfo(String taskUid) {
        if (taskContainer.containsKey(taskUid)) {
            TaskInfo taskInfo = taskContainer.get(taskUid);
            taskInfo.pause = Boolean.TRUE;
        }
    }
}